package com.ash.c.behavioral.visitor;

import com.ash.c.behavioral.visitor.visitable.FloatElement;
import com.ash.c.behavioral.visitor.visitable.StringElement;
import com.ash.c.behavioral.visitor.visitable.Visitable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * <a href='https://www.jianshu.com/p/1f1049d0a0f4'>访问者模式一篇就够了</a>
 * <h1>定义</h1>
 * 封装某些作用于某种数据结构中各元素的操作，它可以在不改变数据结构的前提下定义作用与这些元素的新操作</br>
 * 访问模式可能是行为模式中最复杂的一种模式。</br>
 *
 *
 * <h1>适用场景</h1>
 * 1. 对象结构比较稳定，但经常需要在此对象结构上定义新的操作。</br>
 * 2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作，而需要避免这些操作“污染”这些对象的类，也不希望在增加新操作时修改这些类。</br>
 * <c>思考一个问题，如果下面的objectList不通过访问者模式，想调用这个列表中每个元素对应的方法要怎么做？<c></br>
 *
 * @author Ash
 */
public class Main {

    public static void main(String[] args) {
        List<Object> objectList = new ArrayList<>();
        objectList.add(new StringElement("我是字符串"));
        objectList.add(new StringElement("我是字符串33333"));
        objectList.add(new StringElement("21111我是字符串"));
        objectList.add(new FloatElement(23.222F));
        objectList.add(new FloatElement(22.222F));
        objectList.add(1);

        visitCollection(objectList);

    }

    @SuppressWarnings("rawtypes")
    private static void visitCollection(Collection collection) {
        ConcreteVisitor visitor = new ConcreteVisitor();
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()) {
            Object o = iterator.next();
            if (o instanceof Visitable) {
                ((Visitable) o).accept(visitor);
            }
        }
    }

}
